/*
 * Trader.java
 *
 */
package trader;

import java.util.ArrayList;
import market.StockProduct;
import market.StockService;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.*;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.TopicConnectionFactory;


/**
 *
 * @author Alexandre Metrailler
 * This class executes users action
 */
public class Trader extends Thread  implements MessageListener{

    private StockService marketPrices = new market.StockService();
    private ArrayList<StockProduct> myStock;
    private String name;
    
    //Constructor
    public  Trader(String name){
        this.name = name;
    }
    /**
     * Creates a new instance of Trader
     */
    public void run() {
        initiateMyStock();
       
          
        String topicName = "price";
        TopicConnectionFactory connectionFactory = new com.sun.messaging.TopicConnectionFactory();
        TopicConnection connection = null;
        try {
            connection = connectionFactory.createTopicConnection();
            TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
            Topic topic = new com.sun.messaging.Topic(topicName);
            TopicSubscriber subscriber = session.createSubscriber(topic);
            MessageListener listener = this;
            subscriber.setMessageListener(listener);
            connection.start();
            synchronized (listener) {
                listener.wait();
            }
        } catch (Exception e) {
            System.out.println("Exception occurred: " + e.toString());
            System.exit(1);
        }


    }
    
    public void onMessage(javax.jms.Message message) {
        String msg;
        try {
            msg = ((TextMessage) message).getText();
            //parse the message to get the stock id and the price
            int stockID = Integer.valueOf(msg.substring(0,msg.indexOf("%")));
            double price = Double.valueOf(msg.substring(msg.indexOf("%")+1,msg.length()));
            //update the StockProduct
            ((StockProduct)marketPrices.getDaList().get(stockID -1 )).setStockPrice(price);
           

        } catch (JMSException ex) {
            Logger.getLogger(Trader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    /**
     * Method called by UserGUI when buying or selling
     */
    public void update(int qtty, int stockID, String type) {
        if (type.equals("buy")) {//if the user buiys
            //Here we have to ask via jms the current price of the market
            //get buy price
           double price = ((StockProduct)marketPrices.getDaList().get(stockID)).getStockPrice();
            //inserts in myStock the quantity bought
            ((StockProduct) myStock.get(stockID)).setStockQty(((StockProduct) myStock.get(stockID)).getStockQty() + qtty);
            //inserts in myStock the price
            ((StockProduct) myStock.get(stockID)).setStockPrice(price);
            transaction(type,price,stockID,qtty);

        } else if (type.equals("sell")) {//if the user sells
            if (qtty <= ((StockProduct) myStock.get(stockID)).getStockQty()) {//checks if enough quantity
                //subtracts the quantity in myStock
                ((StockProduct) myStock.get(stockID)).setStockQty(((StockProduct) myStock.get(stockID)).getStockQty() - qtty);
                //computes result
                double adjust = ((qtty * ((StockProduct) marketPrices.getDaList().get(stockID)).getStockPrice())) - ((qtty * ((StockProduct) myStock.get(stockID)).getStockPrice()));
                //adjusts
                ((StockProduct) myStock.get(stockID)).setResult(((StockProduct) myStock.get(stockID)).getResult() + Math.round(adjust));
                //recored last buy price
                ((StockProduct) myStock.get(stockID)).setStockPrice(((StockProduct) marketPrices.getDaList().get(stockID)).getStockPrice());
                double price = ((StockProduct)marketPrices.getDaList().get(stockID)).getStockPrice();
                transaction(type,price,stockID,qtty);
            }
        }
    }

    public ArrayList<StockProduct> getMyStock() {
        return myStock;
    }

    //returns the text to display it in the UserGUI
    public String getText(int stockID) {
        String text = "";
        text = ((StockProduct) myStock.get(stockID)).getStockName() + " (Qtty " + ((StockProduct) myStock.get(stockID)).getStockQty() + ") " + "Result(" + ((StockProduct) myStock.get(stockID)).getResult() + ")";
        return text;
    }

    //returns the trader's result
    public Double getTotalResult() {
        double total = new Double(0);
        for (StockProduct j : myStock) {
            total = total + j.getResult();
        }
        return total;
    }

    //initialise the stockProducts
    public void initiateMyStock() {
        myStock = new ArrayList();
        ArrayList<StockProduct> serviceList = marketPrices.getDaList();
        for (StockProduct j : serviceList) {
            myStock.add(j.clone());
        }
    }

   

    private void transaction(String type, double priceStock, int stockID, int qtty) {
        String queueName = "transaction";
        System.out.println("price " + priceStock);
        ConnectionFactory connectionFactory = new com.sun.messaging.ConnectionFactory();
        Connection connection = null;

        //say to the server what happened
        try {
            connection = connectionFactory.createConnection();

            Queue queue = new com.sun.messaging.Queue(queueName);
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(queue);

            TextMessage message = session.createTextMessage(this.name +" "+ type + " " + Integer.toString(qtty) + " of quote " + Integer.toString(stockID) + " at the price of " + Double.toString(priceStock) );
            System.out.println("Sending transaction [" + message.getText() + "]");

            producer.send(message);
        } catch (Exception e) {
            System.out.println("Exception occurred: " + e.toString());
            System.exit(1);
        }
       
    }
}

